#pragma once
#include <QApplication>
#include <QRect>
#include <QVector3D>
#include <QVector>
#include <cmath>
#include <functional>
// 判断v是否在[min, max]区间内
static bool inRange(int v, int min, int max)
{
	return min <= v && v <= max;
}
// 取[min,max] 区间范围内的值
static int clamp(int v, int min, int max)
{
	if (v < min)
	{
		return min;
	}
	if (v > max)
	{
		return max;
	}
	return v;
}
// 窗口坐标 转 OpenGL顶点坐标。
// 窗口坐标取值范围[0,  w]，坐标圆点在左上角，Y轴正方向朝下
// 顶点坐标取值范围[-1.0, 1.0], 坐标原点在中心点，Y轴正方向朝上
static QVector3D posNormal(int posX, int posY, int windowW, int windowH)
{
	QVector3D pos;
	pos.setZ(0.0f);
	if (windowW <= 0 || windowH <= 0)
	{
		return {};
	}

	pos.setX((2.0 * posX / windowW) - 1.0);
	pos.setY(1.0 - (2.0 * posY / windowH));
	return pos;
}
// 窗口坐标 转 OpenGL顶点坐标
static QVector3D posNormal(const QPoint& pos, const QSize& size)
{
	return posNormal(pos.x(), pos.y(), size.width(), size.height());
}

// 窗口坐标 转 OpenGL顶点坐标
static QVector<QVector3D> rectToVertices(const QRect& rect, int w, int h)
{
	QVector<QVector3D> vertices;
	vertices << posNormal(rect.x(), rect.y(), w, h);
	vertices << posNormal(rect.x() + rect.width(), rect.y(), w, h);
	vertices << posNormal(rect.x() + rect.width(), rect.y() + rect.height(), w, h);
	vertices << posNormal(rect.x(), rect.y() + rect.height(), w, h);
	return vertices;
}
// 背景图坐标 转 窗口坐标
static QPoint backgroundPosToWindowPos(const QPoint& pos, const QSize& backSize, const QSize& windowSize, const qreal& scale)
{
	QPoint ret;
	int	   xOffset = (windowSize.width() - 1.0 * backSize.width() * scale) / 2;
	int	   yOffset = (windowSize.height() - 1.0 * backSize.height() * scale) / 2;
	ret.setX(pos.x() * 1.0 * scale + xOffset);
	ret.setY(pos.y() * 1.0 * scale + yOffset);
	return ret;
}
// 窗口坐标 转 背景图坐标
static QPoint windowPosToBackground(const QPoint& pos, const QSize& backSize, const QSize& windowSize, const qreal& scale)
{
	QPoint ret;
	int	   xOffset = (windowSize.width() - 1.0 * backSize.width() * scale) / 2;
	int	   yOffset = (windowSize.height() - 1.0 * backSize.height() * scale) / 2;
	ret.setX((pos.x() - xOffset) / scale);
	ret.setY((pos.y() - yOffset) / scale);

	return ret;
}
static bool isNormal(qreal v)
{
	return std::isgreater(v, 0.0) && std::islessequal(v, 1.0);
}
template <typename T>
static void safeDelete(T*& ptr)
{
	if (ptr)
	{
		delete ptr;
		ptr = nullptr;
	}
}

using Callback = std::function<void()>;
